#ifndef SYSTEMCALLLAYER_H_
#define SYSTEMCALLLAYER_H_

#include "../fileSystem/FileSystem.h"
#include "../fileSystem/DirectoryEntry.h"
#include "FileDescEntry.h"
#include "Lock.h"


using namespace std;

class SystemCallLayer {

private:
	FileSystem fileSystem;
	vector<FileDescEntry*> openFilesDescTable;
	//maps from inode to it`s lock (containing only locked inodes):
	map<int,Lock> inodeLocksTable;
	map<int,FileDescEntry*>* currProcessFileDescTable;
	//maps from the index in table (fd num) to the open file description table entry
	int lowestFreeDescriptorNum;
	int currProcessID;

	vector<int> findPathDirsInodeNums(vector<string> absolutePathVector,bool includeLastDir);
	void addDirEntry(int containingDir, int dirInodeNum, char* name);
	vector<string> parsePath(string sStringToParse);
	bool lockCheck (int fileInodeNum, string flag);
	bool permissionsCheck (string permissions, string flag);
	void findNextLowestFreeDescriptorNum();

public:
	SystemCallLayer();
	SystemCallLayer(int diskSizeInBytes, int dataBlockSize, int numberOfInodes);
	virtual ~SystemCallLayer();
	int MakeFile(const char* filename, string type, string flag);
	int MakeHLink (char* targetFileName, char* fileName);
	int MakeDir (const char* dirName);
	int RmDir (const char* dirName);
	int resetAndRemoveDir (const char* dirInode);
	int RmFile (const char* fileName);

	int getFileSize(int inode);
	int getNumOfFileInDir(char* dirName);
	/* buf should be 20*getNumOfFileInDir(dirName) */
	int ls (char* dirName, char* buf);
	int Open (const char* fileName, string flag);
	int OpenForSoftLinkFill (const char* fileName, string flag);
	int Close (int fd);
	int Seek (int fd, int location);
	int Read (int fd, int nBytes, unsigned char* buffer);
	int Write (int fd, int nBytes, unsigned char* buffer);

	//Moves the file oldName to newName. This function allows moving files to different directories and \ or change the files name//Moves the file oldName to newName.
	//This function allows moving files to different directories and \ or change the files name
	int moveFile(const char* oldName, const char* newName);

	void findDir (const char* address, string& realAddress);
	int lockRead (int fd);
	int lockWrite (int fd);
	int releaseLockRead (int fd);
	int releaseLockWrite (int fd);
	bool fileIsOpen (int inodeNum);
	void contextSwitch (int pid, map<int,FileDescEntry*>* newProcessTable);
	void incOpenTableConnectionsCounter (int fileInodeNum);
	void fillSoftLink (int softLinkInode, unsigned char* target);
	void test();
	void test1();
};

#endif /* SYSTEMCALLLAYER_H_ */
